home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
3DDEMO.ZIP
/
3D
/
SOURCE
/
POLYGFX.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-21
|
201KB
|
6,649 lines
#include "polygfx.hpp"
// Copyright (c) 1996 by Kerrigan Burgess, all rights reserved.
int FindCode(int x, int y)
{
int code;
if (x<_MinClipX)
code=LEFT;
else
if (x>=_MaxClipX)
code=RIGHT;
else
code=0;
if (y>=_MaxClipY)
code|=BOTTOM;
else
if (y<_MinClipY)
code|=TOP;
return code;
}
// Clipping code gotton from book by Marc B. Sugiyama and Christopher D. Metcalf.
void BresenHamLine(int x1,int y1,int x2,int y2,unsigned char color,
unsigned char *Buffer)
{
int code,code1,code2,x,y,dx,dy,x_inc,y_inc,error=0,count;
code1=FindCode(x1,y1);
code2=FindCode(x2,y2);
while (code1 | code2) // while not fully clipped do.
{
if (code1 & code2) // trivial rejection.
return;
if (code1)
code=code1;
else
code=code2;
if (code & LEFT)
{
x=_MinClipX;
y=y1+((y2-y1)/(float)(x2-x1))*(_MinClipX-x1);
}
else
if (code & RIGHT)
{
x=_MaxClipX-1;
y=y1+((y2-y1)/(float)(x2-x1))*(x-x1);
}
else
if (code & BOTTOM)
{
y=_MaxClipY-1;
x=x1+((x2-x1)/(float)(y2-y1))*(y-y1);
}
else
if (code & TOP)
{
y=_MinClipY;
x=x1+((x2-x1)/(float)(y2-y1))*(_MinClipY-y1);
}
if (code==code1)
code1=FindCode(x1=x,y1=y);
else
code2=FindCode(x2=x,y2=y);
}
Buffer+=(y1<<8)+(y1<<6) + x1;
dx=x2-x1;
dy=y2-y1;
if (dx>=0)
x_inc=1;
else
{
x_inc=-1;
dx=-dx;
}
if (dy>=0)
y_inc=SCREENWIDTH;
else
{
y_inc=-SCREENWIDTH;
dy=-dy;
}
if (dx>dy)
{
for (count=0;count<=dx;count++)
{
*Buffer=color;
error+=dy;
if (error>dx)
{
error-=dx;
Buffer+=y_inc;
}
Buffer+=x_inc;
}
}
else
{
for (count=0;count<=dy;count++)
{
*Buffer=color;
error+=dx;
if (error>0)
{
error-=dy;
Buffer+=x_inc;
}
Buffer+=y_inc;
}
}
}
void Scan_Convert_Wire(void)
{
unsigned char color;
color=LookPal[ _ColorIndex ];
BresenHamLine( _X1,_Y1,_X2,_Y2,color,_RendBuffer);
BresenHamLine( _X2,_Y2,_X3,_Y3,color,_RendBuffer);
BresenHamLine( _X3,_Y3,_X1,_Y1,color,_RendBuffer);
}
//void Scan_Convert_Lambert(void); In assembly module polylow.asm
//void Scan_Convert_Gouraud(void); In assembly module polylow.asm
void Scan_Convert_Phong(void)
{
long LeftX, RightX, LeftDx, RightDx;
long LeftA,RightA,MiddleA;
long LeftDa,RightDa,MiddleDa;
long slope,height;
int x,y,newx,tempx,tempy,tempa,old_X3,old_Y3,old_A3;
int ydiff,newa,ClipLeftX,ClipRightX;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
// NOTE: _A1,_A2,_A3 don't hold intensities but instead hold fixed point angles
// between light and avgnormal vector. We interpolate the angles and then
// index into a PhongTBL to get intensity at that angle. This amazing
// algorithm was thought up by Zach Mortensen (Voltaire/OTM.) mortens1@nersc.gov.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempa=_A1;
_X1=_X2; _Y1=_Y2; _A1=_A2;
_X2=tempx; _Y2=tempy; _A2=tempa;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempa=_A1;
_X1=_X3; _Y1=_Y3; _A1=_A3;
_X3=tempx; _Y3=tempy; _A3=tempa;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2; tempa=_A2;
_X2=_X3; _Y2=_Y3; _A2=_A3;
_X3=tempx; _Y3=tempy; _A3=tempa;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+((slope*(_Y2-_Y1))>>16);
newa = ( ((_Y2-_Y1)*_A3+(_Y3-_Y2)*_A1)*height )>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_A3 = _A3; // save int3 for bottom half.
_X3 = newx;
_Y3 = _Y2;
_A3 = newa;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempa=_A3; _A3=_A2; _A2=tempa;
}
height = 65536/(_Y2-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = LeftX+32768;
LeftA = _A1<<16; // assign angles to left and right side.
RightA = LeftA;
MiddleA = LeftA; // Buffering from left angle.
LeftDa = (_A2 - _A1)*height; // compute intensity deltas.
RightDa = (_A3 - _A1)*height;
ClipLeftX = ( LeftX>>16 ); // just starting and ending x-coords
ClipRightX = ( RightX>>16 );
MiddleDa = 0;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 ); // just starting and ending x-coords
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ];
MiddleA+=MiddleDa;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ];
MiddleA += MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftA += LeftDa;
RightA += RightDa;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_A1 = _A2;
_X2 = _X3;
_A2 = _A3;
_X3 = old_X3;
_Y3 = old_Y3;
_A3 = old_A3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempa=_A2; _A2=_A1; _A1=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = (_X2<<16)+32768;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = _A2<<16;
MiddleA = LeftA; // Buffering from left intensity.
LeftDa = (_A3 - _A1)*height; // compute intensity deltas.
RightDa = (_A3 - _A2)*height;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ];
MiddleA += MiddleDa;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ];
MiddleA += MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftA += LeftDa;
RightA += RightDa;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
}
void Scan_Convert_TextureL(void)
{
long LeftX, RightX, LeftDx, RightDx;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV;
long LeftDu,LeftDv,RightDu,RightDv;
long width,height,slope;
int ClipLeftX,ClipRightX,ydiff;
int x,y,newx,newu,newv,tempx,tempy,tempu,tempv;
int old_X3,old_Y3,old_U3,old_V3;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1;
_U1=_U2; _V1=_V2;
_U2=tempu; _V2=tempv;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1;
_U1=_U3; _V1=_V3;
_U3=tempu; _V3=tempv;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2;
_U2=_U3; _V2=_V3;
_U3=tempu; _V3=tempv;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = ( ((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height )>>16;
newv = ( ((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height )>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
}
height = 65536/(_Y2-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
ScanU = 0;
ScanV = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
}
void Scan_Convert_TextureG(void)
{
long LeftX, RightX, LeftDx, RightDx;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV,LeftI,RightI,MiddleI;
long LeftDu,LeftDv,RightDu,RightDv,LeftDi,RightDi,MiddleDi;
long height,width,slope,ydiff;
int ClipLeftX,ClipRightX;
int x,y,newi,newx,newu,newv,tempx,tempy,tempu,tempv,tempi;
int old_X3,old_Y3,old_U3,old_V3,old_I3;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1; tempi=_I1;
_U1=_U2; _V1=_V2; _I1=_I2;
_U2=tempu; _V2=tempv; _I2=tempi;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1; tempi=_I1;
_U1=_U3; _V1=_V3; _I1=_I3;
_U3=tempu; _V3=tempv; _I3=tempi;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2; tempi=_I2;
_U2=_U3; _V2=_V3; _I2=_I3;
_U3=tempu; _V3=tempv; _I3=tempi;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
newi = (((_Y2-_Y1)*_I3+(_Y3-_Y2)*_I1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
old_I3 = _I3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
_I3 = newi;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
tempi=_I3; _I3=_I2; _I2=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftDi = (_I2-_I1)*height; // compute intensity deltas.
RightDi = (_I3-_I1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = LeftI;
ScanU = 0; // because of Flat bottom.
ScanV = 0;
MiddleDi = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_I1 = _I2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_I2 = _I3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
_I3 = old_I3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
tempi=_I2; _I2=_I1; _I1=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftDi = (_I3-_I1)*height; // compute intensity deltas.
RightDi = (_I3-_I2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = _I2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
}
void Scan_Convert_TextureP(void)
{
long LeftX, RightX, LeftDx, RightDx;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV,LeftA,RightA,MiddleA;
long LeftDu,LeftDv,RightDu,RightDv,LeftDa,RightDa,MiddleDa;
long height,width,slope,ydiff;
int ClipLeftX,ClipRightX;
int x,y,newa,newx,newu,newv,tempx,tempy,tempu,tempv,tempa;
int old_X3,old_Y3,old_U3,old_V3,old_A3;
int GENERAL;
unsigned char *Buffer;
// NOTE: _A1,_A2,_A3 don't hold intensities but instead hold fixed point angles
// between light and avgnormal vector. We interpolate the angles and then
// index into a PhongTBL to get intensity at that angle. This amazing
// algorithm was thought up by Zach Mortensen (Voltaire/OTM.) mortens1@nersc.gov.
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1; tempa=_A1;
_U1=_U2; _V1=_V2; _A1=_A2;
_U2=tempu; _V2=tempv; _A2=tempa;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1; tempa=_A1;
_U1=_U3; _V1=_V3; _A1=_A3;
_U3=tempu; _V3=tempv; _A3=tempa;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2; tempa=_A2;
_U2=_U3; _V2=_V3; _A2=_A3;
_U3=tempu; _V3=tempv; _A3=tempa;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
newa = (((_Y2-_Y1)*_A3+(_Y3-_Y2)*_A1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
old_A3 = _A3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
_A3 = newa;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
tempa=_A3; _A3=_A2; _A2=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftDa = (_A2-_A1)*height; // compute intensity deltas.
RightDa = (_A3-_A1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = LeftA;
ScanU = 0; // because of Flat bottom.
ScanV = 0;
MiddleDa = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_A1 = _A2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_A2 = _A3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
_A3 = old_A3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
tempa=_A2; _A2=_A1; _A1=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftDa = (_A3-_A1)*height; // compute intensity deltas.
RightDa = (_A3-_A2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = _A2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
}
void Scan_Convert_LambertT(void)
{
long LeftX, RightX, LeftDx, RightDx;
long slope, height;
int x,y,ydiff,newx,tempx,tempy,old_X3,old_Y3,ClipLeftX,ClipRightX;
int GENERAL;
int fgcolor;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
fgcolor=( _TransLevel<<16) + (LookPal[ _ColorIndex ]<<8); // TransTbl[ translevel*65536 + fg*256 + b].
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
slope = ((_X3-_X1)<<16)/(_Y3-_Y1);
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
_X3 = newx;
_Y3 = _Y2;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY-_Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( LeftX>>16 );x<=( RightX>>16 );x++)
{
Buffer[x]=TransTBL[ fgcolor + Buffer[x] ];
}
LeftX += LeftDx;
RightX += RightDx;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
continue;
}
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
continue;
}
ClipRightX = _MaxClipX;
}
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBL[ fgcolor + Buffer[x] ];
}
LeftX += LeftDx;
RightX += RightDx;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_X2 = _X3;
_X3 = old_X3;
_Y3 = old_Y3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X1; _X1=_X2; _X2=tempx;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY-_Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( LeftX>>16 );x<=( RightX>>16 );x++)
{
Buffer[x]=TransTBL[ fgcolor + Buffer[x] ];
}
LeftX += LeftDx;
RightX += RightDx;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
continue;
}
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
continue;
}
ClipRightX = _MaxClipX;
}
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBL[ fgcolor + Buffer[x] ];
}
LeftX += LeftDx;
RightX += RightDx;
}
}
}
void Scan_Convert_GouraudT(void)
{
long LeftX, RightX, LeftDx, RightDx;
long LeftI,RightI,MiddleI;
long LeftDi,RightDi,MiddleDi;
long slope,height;
int x,y,ydiff,newx,tempx,tempy,tempi;
int old_X3,old_Y3,old_I3,newi,ClipLeftX,ClipRightX;
int GENERAL;
unsigned char *Buffer;
unsigned char *TransTBLptr;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempi=_I1;
_X1=_X2; _Y1=_Y2; _I1=_I2;
_X2=tempx; _Y2=tempy; _I2=tempi;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempi=_I1;
_X1=_X3; _Y1=_Y3; _I1=_I3;
_X3=tempx; _Y3=tempy; _I3=tempi;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2; tempi=_I2;
_X2=_X3; _Y2=_Y3; _I2=_I3;
_X3=tempx; _Y3=tempy; _I3=tempi;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
TransTBLptr = TransTBL;
TransTBLptr += ( _TransLevel<<16); // Buffer at level of transparency.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newi = ( (((_Y2-_Y1)*_I3+(_Y3-_Y2)*_I1)*height)>>16 );
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_I3 = _I3; // save int3 for bottom half.
_X3 = newx;
_Y3 = _Y2;
_I3 = newi;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempi=_I3; _I3=_I2; _I2=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = LeftX+32768;
LeftDi = (_I2 - _I1)*height; // compute intensity deltas.
RightDi = (_I3 - _I1)*height;
MiddleDi = 0;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = LeftI;
MiddleI = LeftI; // Buffering from left intensity.
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
MiddleI = LeftI;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/(1+ClipRightX-ClipLeftX); // to avoid divide by 0.
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ _ColorIndex + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
MiddleI+=MiddleDi;
}
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
MiddleI = LeftI;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ _ColorIndex + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
MiddleI += MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftI += LeftDi;
RightI += RightDi;
MiddleI = LeftI;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_I1 = _I2;
_X2 = _X3;
_I2 = _I3;
_X3 = old_X3;
_Y3 = old_Y3;
_I3 = old_I3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempi=_I2; _I2=_I1; _I1=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = (_X2<<16)+32768;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = _I2<<16;
MiddleI = LeftI; // Buffering from left intensity.
LeftDi = (_I3 - _I1)*height; // compute intensity deltas.
RightDi = (_I3 - _I2)*height;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
MiddleI = LeftI;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ _ColorIndex + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
MiddleI += MiddleDi;
}
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
MiddleI = LeftI;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ _ColorIndex + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
MiddleI += MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftI += LeftDi;
RightI += RightDi;
MiddleI = LeftI;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDi = (RightI - LeftI)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
}
void Scan_Convert_PhongT(void)
{
long LeftX, RightX, LeftDx, RightDx;
long LeftA,RightA,MiddleA;
long LeftDa,RightDa,MiddleDa;
long slope,height;
int x,y,ydiff,newx,tempx,tempy,tempa;
int old_X3,old_Y3,old_A3,newa,ClipLeftX,ClipRightX;
int GENERAL;
unsigned char *Buffer;
unsigned char *TransTBLptr;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempa=_A1;
_X1=_X2; _Y1=_Y2; _A1=_A2;
_X2=tempx; _Y2=tempy; _A2=tempa;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempa=_A1;
_X1=_X3; _Y1=_Y3; _A1=_A3;
_X3=tempx; _Y3=tempy; _A3=tempa;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2; tempa=_A2;
_X2=_X3; _Y2=_Y3; _A2=_A3;
_X3=tempx; _Y3=tempy; _A3=tempa;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
TransTBLptr = TransTBL;
TransTBLptr += ( _TransLevel<<16); // Buffer at level of transparency.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newa = ( (((_Y2-_Y1)*_A3+(_Y3-_Y2)*_A1)*height)>>16 );
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_A3 = _A3; // save int3 for bottom half.
_X3 = newx;
_Y3 = _Y2;
_A3 = newa;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempa=_A3; _A3=_A2; _A2=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = LeftX+32768;
LeftDa = (_A2 - _A1)*height; // compute intensity deltas.
RightDa = (_A3 - _A1)*height;
MiddleDa = 0;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = LeftA;
MiddleA = LeftA; // Buffering from left intensity.
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ _ColorIndex + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
MiddleA+=MiddleDa;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ _ColorIndex + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
MiddleA += MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftA += LeftDa;
RightA += RightDa;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_A1 = _A2;
_X2 = _X3;
_A2 = _A3;
_X3 = old_X3;
_Y3 = old_Y3;
_A3 = old_A3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempa=_A2; _A2=_A1; _A1=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = (_X2<<16)+32768;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = _A2<<16;
MiddleA = LeftA; // Buffering from left intensity.
LeftDa = (_A3 - _A1)*height; // compute intensity deltas.
RightDa = (_A3 - _A2)*height;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ _ColorIndex + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
MiddleA += MiddleDa;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ _ColorIndex + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
MiddleA += MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftA += LeftDa;
RightA += RightDa;
MiddleA = LeftA;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
MiddleDa = (RightA - LeftA)/( 1+ClipRightX-ClipLeftX ); // to avoid divide by 0.
}
}
}
void Scan_Convert_TextureLT(void)
{
long LeftX, RightX, LeftDx, RightDx;
long width,height,slope;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV;
long LeftDu,LeftDv,RightDu,RightDv;
int ClipLeftX,ClipRightX;
int x,y,ydiff,newx,newu,newv,tempx,tempy,tempu,tempv;
int old_X3,old_Y3,old_U3,old_V3;
int GENERAL;
unsigned char *Buffer;
unsigned char *TransTBLptr;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1;
_U1=_U2; _V1=_V2;
_U2=tempu; _V2=tempv;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1;
_U1=_U3; _V1=_V3;
_U3=tempu; _V3=tempv;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2;
_U2=_U3; _V2=_V3;
_U3=tempu; _V3=tempv;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
TransTBLptr = TransTBL;
TransTBLptr += ( _TransLevel<<16); // Buffer at level of transparency.
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
ScanU = 0;
ScanV = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + _ColorIndex ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + _ColorIndex ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + _ColorIndex ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + _ColorIndex ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
}
void Scan_Convert_TextureGT(void)
{
long LeftX, RightX, LeftDx, RightDx;
long height,width,slope;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV,LeftI,RightI,MiddleI;
long LeftDu,LeftDv,RightDu,RightDv,LeftDi,RightDi,MiddleDi;
int ClipLeftX,ClipRightX;
int x,y,ydiff,newi,newx,newu,newv,tempx,tempy,tempu,tempv,tempi;
int old_X3,old_Y3,old_U3,old_V3,old_I3;
int GENERAL;
unsigned char *Buffer;
unsigned char *TransTBLptr;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1; tempi=_I1;
_U1=_U2; _V1=_V2; _I1=_I2;
_U2=tempu; _V2=tempv; _I2=tempi;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1; tempi=_I1;
_U1=_U3; _V1=_V3; _I1=_I3;
_U3=tempu; _V3=tempv; _I3=tempi;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2; tempi=_I2;
_U2=_U3; _V2=_V3; _I2=_I3;
_U3=tempu; _V3=tempv; _I3=tempi;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
TransTBLptr=TransTBL;
TransTBLptr+=( _TransLevel<<16);
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
newi = (((_Y2-_Y1)*_I3+(_Y3-_Y2)*_I1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
old_I3 = _I3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
_I3 = newi;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
tempi=_I3; _I3=_I2; _I2=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftDi = (_I2-_I1)*height; // compute intensity deltas.
RightDi = (_I3-_I1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = LeftI;
ScanU = 0; // because of Flat bottom.
ScanV = 0;
MiddleDi = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_I1 = _I2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_I2 = _I3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
_I3 = old_I3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
tempi=_I2; _I2=_I1; _I1=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftDi = (_I3-_I1)*height; // compute intensity deltas.
RightDi = (_I3-_I2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = _I2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + (MiddleI>>16) ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
}
}
}
void Scan_Convert_TexturePT(void)
{
long LeftX, RightX, LeftDx, RightDx;
long height,width,slope;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV,LeftA,RightA,MiddleA;
long LeftDu,LeftDv,RightDu,RightDv,LeftDa,RightDa,MiddleDa;
int ClipLeftX,ClipRightX;
int x,y,ydiff,newa,newx,newu,newv,tempx,tempy,tempu,tempv,tempa;
int old_X3,old_Y3,old_U3,old_V3,old_A3;
int GENERAL;
unsigned char *Buffer;
unsigned char *TransTBLptr;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1; tempa=_A1;
_U1=_U2; _V1=_V2; _A1=_A2;
_U2=tempu; _V2=tempv; _A2=tempa;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1; tempa=_A1;
_U1=_U3; _V1=_V3; _A1=_A3;
_U3=tempu; _V3=tempv; _A3=tempa;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2; tempa=_A2;
_U2=_U3; _V2=_V3; _A2=_A3;
_U3=tempu; _V3=tempv; _A3=tempa;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
TransTBLptr=TransTBL;
TransTBLptr+=( _TransLevel<<16);
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
newa = (((_Y2-_Y1)*_A3+(_Y3-_Y2)*_A1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
old_A3 = _A3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
_A3 = newa;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
tempa=_A3; _A3=_A2; _A2=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftDa = (_A2-_A1)*height; // compute intensity deltas.
RightDa = (_A3-_A1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = LeftA;
ScanU = 0; // because of Flat bottom.
ScanV = 0;
MiddleDa = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_A1 = _A2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_A2 = _A3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
_A3 = old_A3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
tempa=_A2; _A2=_A1; _A1=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftDa = (_A3-_A1)*height; // compute intensity deltas.
RightDa = (_A3-_A2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = _A2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=TransTBLptr[ ( LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8 ) ] + PhongTBL[ (MiddleA>>16) ] ]<<8 ) + Buffer[x] ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
}
}
}
void Scan_Convert_LambertH(void)
{
long LeftX, RightX, LeftDx, RightDx;
long height,slope;
long hazevalue,hazeintensity;
int start,end,y,newx,tempx,tempy,old_X3,old_Y3,ClipLeftX,ClipRightX;
int GENERAL;
unsigned char color;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
hazevalue=( _AvgZ<<16)/1000;
hazeintensity=(64*hazevalue)>>16;
color=HazeTBL[ (LookPal[ _ColorIndex ]<<6) + hazeintensity ];
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
slope = ((_X3-_X1)<<16)/(_Y3-_Y1);
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
_X3 = newx;
_Y3 = _Y2;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
}
height = 65536/(_Y3-_Y1); // point 16 format.
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768; // 32768 is 0.5 in 16 point format.
if (_Y1 < _MinClipY)
{
LeftX = LeftX+LeftDx*(_MinClipY-_Y1);
RightX = RightX+RightDx*(_MinClipY-_Y1);
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
start = LeftX>>16;
end = RightX>>16;
Line((unsigned char *)Buffer+start,color,1+end-start);
LeftX += LeftDx;
RightX += RightDx;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
LeftX += LeftDx;
RightX += RightDx;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
continue;
ClipLeftX = _MinClipX;
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
continue;
ClipRightX = _MaxClipX;
}
Line((unsigned char *)Buffer+ClipLeftX,color,1+ClipRightX-ClipLeftX);
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_X2 = _X3;
_X3 = old_X3;
_Y3 = old_Y3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X1; _X1=_X2; _X2=tempx;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768; // 32768 is 0.5 in 16 point format.
if (_Y1 < _MinClipY)
{
LeftX = LeftX+LeftDx*(_MinClipY-_Y1);
RightX = RightX+RightDx*(_MinClipY-_Y1);
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
start = LeftX>>16;
end = RightX>>16;
Line((unsigned char *)Buffer+start,color,1+end-start);
LeftX+=LeftDx;
RightX+=RightDx;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
LeftX+=LeftDx;
RightX+=RightDx;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
continue; // totally off screen!
ClipLeftX = _MinClipX;
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
continue;
ClipRightX = _MaxClipX;
}
Line((unsigned char *)Buffer+ClipLeftX,color,1+ClipRightX-ClipLeftX);
}
}
}
void Scan_Convert_GouraudH(void)
{
long LeftX, RightX, LeftDx, RightDx;
long LeftI,RightI,MiddleI;
long LeftDi,RightDi,MiddleDi;
long LeftH,RightH,MiddleH;
long LeftDh,RightDh,MiddleDh;
long slope,height,width,hazevalue;
int x,y,newx,newi,newh,tempx,tempy,tempz,tempi,temph;
int h1,h2,h3,old_X3,old_Y3,oldh3,old_I3;
int ydiff,ClipLeftX,ClipRightX;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempz=_Z1;
_X1=_X2; _Y1=_Y2; _Z1=_Z2;
_X2=tempx; _Y2=tempy; _Z2=tempz;
tempi=_I2; // switch the intensities also.
_I2=_I1;
_I1=tempi;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempz=_Z1;
_X1=_X3; _Y1=_Y3; _Z1=_Z3;
_X3=tempx; _Y3=tempy; _Z3=tempz;
tempi=_I3;
_I3=_I1;
_I1=tempi;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2; tempz=_Z2;
_X2=_X3; _Y2=_Y3; _Z2=_Z3;
_X3=tempx; _Y3=tempy; _Z3=tempz;
tempi=_I3;
_I3=_I2;
_I2=tempi;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
hazevalue=(_Z1<<16)/1000;
h1=(64*hazevalue)>>16;
hazevalue=(_Z2<<16)/1000;
h2=(64*hazevalue)>>16;
hazevalue=(_Z3<<16)/1000;
h3=(64*hazevalue)>>16;
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
newi = (((_Y2-_Y1)*_I3+(_Y3-_Y2)*_I1)*height)>>16;
slope = (_X3-_X1)*height;
newx = _X1+((slope*(_Y2-_Y1))>>16);
newh = (((_Y2-_Y1)*h3+(_Y3-_Y2)*h1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
oldh3 = h3;
old_I3 = _I3; // save int3 for bottom half.
_X3 = newx;
_Y3 = _Y2;
h3 = newh;
_I3 = newi;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
temph=h3; h3=h2; h2=temph;
tempi=_I3; _I3=_I2; _I2=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = LeftX+32768;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = LeftI;
MiddleI = LeftI; // Buffering from left intensity.
LeftDi = (_I2 - _I1)*height; // compute intensity deltas.
RightDi = (_I3 - _I1)*height;
MiddleDi = 0;
LeftH = h1<<16; // assign intensity to left and right side.
RightH = LeftH;
MiddleH = LeftH; // Buffering from left intensity.
LeftDh = (h2 - h1)*height; // compute intensity deltas.
RightDh = (h3 - h1)*height;
MiddleDh = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
MiddleI = LeftI;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
MiddleH = LeftH;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPal[ _ColorIndex + ( MiddleI>>16 ) ]<<6) + ( MiddleH>>16 ) ];
MiddleI += MiddleDi;
MiddleH += MiddleDh;
}
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
MiddleI = LeftI;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPal[ _ColorIndex + ( MiddleI>>16 ) ]<<6) + ( MiddleH>>16 ) ];
MiddleI += MiddleDi;
MiddleH += MiddleDh;
}
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
MiddleI = LeftI;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_I1 = _I2;
h1 = h2;
_X2 = _X3;
_I2 = _I3;
h2 = h3;
_X3 = old_X3;
_Y3 = old_Y3;
_I3 = old_I3;
h3 = oldh3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
temph=h2; h2=h1; h1=temph;
tempi=_I2; _I2=_I1; _I1=tempi;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = (_X2<<16)+32768;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = _I2<<16;
MiddleI = LeftI; // Buffering from left intensity.
LeftDi = (_I3 - _I1)*height; // compute intensity deltas.
RightDi = (_I3 - _I2)*height;
LeftH = h1<<16; // assign intensity to left and right side.
RightH = h2<<16;
MiddleH = LeftH; // Buffering from left intensity.
LeftDh = (h3 - h1)*height; // compute intensity deltas.
RightDh = (h3 - h2)*height;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
MiddleI = LeftI;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
MiddleH = LeftH;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPal[ _ColorIndex + ( MiddleI>>16 ) ]<<6) + ( MiddleH>>16 ) ];
MiddleI += MiddleDi;
MiddleH += MiddleDh;
}
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
MiddleI = LeftI;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPal[ _ColorIndex + ( MiddleI>>16 ) ]<<6) + ( MiddleH>>16 ) ];
MiddleI += MiddleDi;
MiddleH += MiddleDh;
}
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
MiddleI = LeftI;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDi = (RightI - LeftI)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
}
void Scan_Convert_PhongH(void)
{
long LeftX, RightX, LeftDx, RightDx;
long LeftA,RightA,MiddleA;
long LeftDa,RightDa,MiddleDa;
long LeftH,RightH,MiddleH;
long LeftDh,RightDh,MiddleDh;
long slope,height,width,hazevalue;
int x,y,newx,newa,newh,tempx,tempy,tempz,tempa,temph;
int h1,h2,h3,old_X3,old_Y3,oldh3,old_A3;
int ydiff,ClipLeftX,ClipRightX;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempz=_Z1;
_X1=_X2; _Y1=_Y2; _Z1=_Z2;
_X2=tempx; _Y2=tempy; _Z2=tempz;
tempa=_A2; // switch the intensities also.
_A2=_A1;
_A1=tempa;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1; tempz=_Z1;
_X1=_X3; _Y1=_Y3; _Z1=_Z3;
_X3=tempx; _Y3=tempy; _Z3=tempz;
tempa=_A3;
_A3=_A1;
_A1=tempa;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2; tempz=_Z2;
_X2=_X3; _Y2=_Y3; _Z2=_Z3;
_X3=tempx; _Y3=tempy; _Z3=tempz;
tempa=_A3;
_A3=_A2;
_A2=tempa;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
// now ALL vertices are in correct Counter-Clockwise order.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
hazevalue=(_Z1<<16)/1000;
h1=(64*hazevalue)>>16;
hazevalue=(_Z2<<16)/1000;
h2=(64*hazevalue)>>16;
hazevalue=(_Z3<<16)/1000;
h3=(64*hazevalue)>>16;
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
newa = (((_Y2-_Y1)*_A3+(_Y3-_Y2)*_A1)*height)>>16;
slope = (_X3-_X1)*height;
newx = _X1+((slope*(_Y2-_Y1))>>16);
newh = (((_Y2-_Y1)*h3+(_Y3-_Y2)*h1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
oldh3 = h3;
old_A3 = _A3; // save int3 for bottom half.
_X3 = newx;
_Y3 = _Y2;
h3 = newh;
_A3 = newa;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
temph=h3; h3=h2; h2=temph;
tempa=_A3; _A3=_A2; _A2=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = LeftX+32768;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = LeftA;
MiddleA = LeftA; // Buffering from left intensity.
LeftDa = (_A2 - _A1)*height; // compute intensity deltas.
RightDa = (_A3 - _A1)*height;
MiddleDa = 0;
LeftH = h1<<16; // assign intensity to left and right side.
RightH = LeftH;
MiddleH = LeftH; // Buffering from left intensity.
LeftDh = (h2 - h1)*height; // compute intensity deltas.
RightDh = (h3 - h1)*height;
MiddleDh = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
MiddleA = LeftA;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
MiddleH = LeftH;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ]<<6) + ( MiddleH>>16 ) ];
MiddleA += MiddleDa;
MiddleH += MiddleDh;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ]<<6) + ( MiddleH>>16 ) ];
MiddleA += MiddleDa;
MiddleH += MiddleDh;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_A1 = _A2;
h1 = h2;
_X2 = _X3;
_A2 = _A3;
h2 = h3;
_X3 = old_X3;
_Y3 = old_Y3;
_A3 = old_A3;
h3 = oldh3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
temph=h2; h2=h1; h1=temph;
tempa=_A2; _A2=_A1; _A1=tempa;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftX = _X1<<16; // assign Buffering coords.
RightX = (_X2<<16)+32768;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = _A2<<16;
MiddleA = LeftA; // Buffering from left intensity.
LeftDa = (_A3 - _A1)*height; // compute intensity deltas.
RightDa = (_A3 - _A2)*height;
LeftH = h1<<16; // assign intensity to left and right side.
RightH = h2<<16;
MiddleH = LeftH; // Buffering from left intensity.
LeftDh = (h3 - h1)*height; // compute intensity deltas.
RightDh = (h3 - h2)*height;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
MiddleA = LeftA;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
MiddleH = LeftH;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ]<<6) + ( MiddleH>>16 ) ];
MiddleA += MiddleDa;
MiddleH += MiddleDh;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh; // move the intensity by
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<=ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ _ColorIndex + PhongTBL[ ( MiddleA>>16 ) ] ]<<6) + ( MiddleH>>16 ) ];
MiddleA += MiddleDa;
MiddleH += MiddleDh;
}
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
MiddleA = LeftA;
LeftH += LeftDh; // update the intensities and slopes.
RightH += RightDh;
MiddleH = LeftH;
LeftX += LeftDx;
RightX += RightDx;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
MiddleDa = (RightA - LeftA)/width;
MiddleDh = (RightH - LeftH)/width;
}
}
}
void Scan_Convert_TextureLH(void)
{
long LeftX, RightX, LeftDx, RightDx;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV;
long LeftDu,LeftDv,RightDu,RightDv;
long hazevalue,hazeintensity,width,height,slope;
int ClipLeftX,ClipRightX,ydiff;
int x,y,newx,newu,newv,tempx,tempy,tempu,tempv;
int old_X3,old_Y3,old_U3,old_V3;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1;
_U1=_U2; _V1=_V2;
_U2=tempu; _V2=tempv;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1;
_U1=_U3; _V1=_V3;
_U3=tempu; _V3=tempv;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2;
_U2=_U3; _V2=_V3;
_U3=tempu; _V3=tempv;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
hazevalue=( _AvgZ<<16)/1000;
hazeintensity=(64*hazevalue)>>16;
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = ( ((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height )>>16;
newv = ( ((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height )>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
}
height = 65536/(_Y2-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
ScanU = 0;
ScanV = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ]<<6) + hazeintensity];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ]<<6) + hazeintensity];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ]<<6) + hazeintensity];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + _ColorIndex ]<<6) + hazeintensity];
u+=ScanU;
v+=ScanV;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
}
}
}
void Scan_Convert_TextureGH(void)
{
long LeftX, RightX, LeftDx, RightDx;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV,LeftI,RightI,MiddleI;
long LeftDu,LeftDv,RightDu,RightDv,LeftDi,RightDi,MiddleDi;
long hazevalue,height,width,slope,ydiff;
long LeftH,RightH,MiddleH;
long LeftDh,RightDh,MiddleDh;
int h1,h2,h3,newh,ClipLeftX,ClipRightX;
int x,y,newi,newx,newu,newv,tempx,tempy,tempu,tempv,tempi,temph;
int old_X3,old_Y3,old_U3,old_V3,old_I3,oldh3;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1; tempi=_I1;
_U1=_U2; _V1=_V2; _I1=_I2;
_U2=tempu; _V2=tempv; _I2=tempi;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1; tempi=_I1;
_U1=_U3; _V1=_V3; _I1=_I3;
_U3=tempu; _V3=tempv; _I3=tempi;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2; tempi=_I2;
_U2=_U3; _V2=_V3; _I2=_I3;
_U3=tempu; _V3=tempv; _I3=tempi;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
hazevalue=(_Z1<<16)/1000;
h1=(64*hazevalue)>>16;
hazevalue=(_Z2<<16)/1000;
h2=(64*hazevalue)>>16;
hazevalue=(_Z3<<16)/1000;
h3=(64*hazevalue)>>16;
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
newi = (((_Y2-_Y1)*_I3+(_Y3-_Y2)*_I1)*height)>>16;
newh = (((_Y2-_Y1)*h3+(_Y3-_Y2)*h1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
old_I3 = _I3;
oldh3 = h3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
_I3 = newi;
h3 = newh;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
tempi=_I3; _I3=_I2; _I2=tempi;
temph=h3; h3=h2; h2=temph;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftDi = (_I2-_I1)*height; // compute intensity deltas.
RightDi = (_I3-_I1)*height;
LeftDh = (h2-h1)*height;
RightDh = (h3-h1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = LeftI;
LeftH = h1<<16;
RightH = LeftH;
ScanU = 0; // because of Flat bottom.
ScanV = 0;
MiddleDi = 0;
MiddleDh = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
MiddleH=LeftH;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
MiddleH=LeftH;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_I1 = _I2;
h1 = h2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_I2 = _I3;
h2 = h3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
_I3 = old_I3;
h3 = oldh3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
tempi=_I2; _I2=_I1; _I1=tempi;
temph=h2; h2=h1; h1=temph;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftDi = (_I3-_I1)*height; // compute intensity deltas.
RightDi = (_I3-_I2)*height;
LeftDh = (h3-h1)*height;
RightDh = (h3-h2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
LeftI = _I1<<16; // assign intensity to left and right side.
RightI = _I2<<16;
LeftH = h1<<16;
RightH = h2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftI = LeftI+LeftDi*ydiff;
RightI = RightI+RightDi*ydiff;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
MiddleH=LeftH;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi; // update the intensities and slopes.
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleI=LeftI;
MiddleH=LeftH;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleI = LeftI + (_MinClipX - ClipLeftX)*MiddleDi; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPal[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + (MiddleI>>16) ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleI+=MiddleDi;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftI += LeftDi;
RightI += RightDi;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDi = (RightI-LeftI)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
}
void Scan_Convert_TexturePH(void)
{
long LeftX, RightX, LeftDx, RightDx;
long u,v,ScanU,ScanV,LeftU,LeftV,RightU,RightV,LeftA,RightA,MiddleA;
long LeftDu,LeftDv,RightDu,RightDv,LeftDa,RightDa,MiddleDa;
long hazevalue,height,width,slope,ydiff;
long LeftH,RightH,MiddleH;
long LeftDh,RightDh,MiddleDh;
int h1,h2,h3,newh,ClipLeftX,ClipRightX;
int x,y,newa,newx,newu,newv,tempx,tempy,tempu,tempv,tempa,temph;
int old_X3,old_Y3,old_U3,old_V3,old_A3,oldh3;
int GENERAL;
unsigned char *Buffer;
if ( (_X1==_X2 && _X2==_X3) || (_Y1==_Y2 && _Y2==_Y3) )
return; // degenerated into lines.
if (_Y2<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X2; _Y1=_Y2;
_X2=tempx; _Y2=tempy;
tempu=_U1; tempv=_V1; tempa=_A1;
_U1=_U2; _V1=_V2; _A1=_A2;
_U2=tempu; _V2=tempv; _A2=tempa;
}
if (_Y3<_Y1) // switch. They're in the wrong order.
{
tempx=_X1; tempy=_Y1;
_X1=_X3; _Y1=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U1; tempv=_V1; tempa=_A1;
_U1=_U3; _V1=_V3; _A1=_A3;
_U3=tempu; _V3=tempv; _A3=tempa;
}
if (_Y3<_Y2) // switch. They're in the wrong order.
{
tempx=_X2; tempy=_Y2;
_X2=_X3; _Y2=_Y3;
_X3=tempx; _Y3=tempy;
tempu=_U2; tempv=_V2; tempa=_A2;
_U2=_U3; _V2=_V3; _A2=_A3;
_U3=tempu; _V3=tempv; _A3=tempa;
}
if (_Y3<_MinClipY || _Y1>_MaxClipY ||
(_X1<_MinClipX && _X2<_MinClipX && _X3<_MinClipX) ||
(_X1>_MaxClipX && _X2>_MaxClipX && _X3>_MaxClipX) )
return; // do trivial rejection.
GENERAL=FALSE; // reset cases (for Triangle).
Buffer=_RendBuffer; // save starting point of Buffer.
hazevalue=(_Z1<<16)/1000;
h1=(64*hazevalue)>>16;
hazevalue=(_Z2<<16)/1000;
h2=(64*hazevalue)>>16;
hazevalue=(_Z3<<16)/1000;
h3=(64*hazevalue)>>16;
if (_Y1==_Y2)
goto FLAT_TOP;
if (_Y2==_Y3)
goto FLAT_BOTTOM;
else
GENERAL=TRUE;
height = 65536/(_Y3-_Y1);
slope = (_X3-_X1)*height;
newx = _X1+( (slope*(_Y2-_Y1))>>16 );
newu = (((_Y2-_Y1)*_U3+(_Y3-_Y2)*_U1)*height)>>16;
newv = (((_Y2-_Y1)*_V3+(_Y3-_Y2)*_V1)*height)>>16;
newa = (((_Y2-_Y1)*_A3+(_Y3-_Y2)*_A1)*height)>>16;
newh = (((_Y2-_Y1)*h3+(_Y3-_Y2)*h1)*height)>>16;
old_X3 = _X3; // save values for later.
old_Y3 = _Y3;
old_U3 = _U3;
old_V3 = _V3;
old_A3 = _A3;
oldh3 = h3;
_X3 = newx;
_Y3 = _Y2;
_U3 = newu;
_V3 = newv;
_A3 = newa;
h3 = newh;
FLAT_BOTTOM:
if (_X3<_X2)
{
tempx=_X3; _X3=_X2; _X2=tempx;
tempu=_U3; _U3=_U2; _U2=tempu;
tempv=_V3; _V3=_V2; _V2=tempv;
tempa=_A3; _A3=_A2; _A2=tempa;
temph=h3; h3=h2; h2=temph;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X2-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X1)*height;
LeftDu = (_U2-_U1)*height;
LeftDv = (_V2-_V1)*height;
RightDu = (_U3-_U1)*height;
RightDv = (_V3-_V1)*height;
LeftDa = (_A2-_A1)*height; // compute intensity deltas.
RightDa = (_A3-_A1)*height;
LeftDh = (h2-h1)*height;
RightDh = (h3-h1)*height;
LeftX = _X1<<16;
RightX = LeftX+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = LeftU;
RightV = LeftV;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = LeftA;
LeftH = h1<<16;
RightH = LeftH;
ScanU = 0; // because of Flat bottom.
ScanV = 0;
MiddleDa = 0;
MiddleDh = 0;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
MiddleH=LeftH;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
MiddleH=LeftH;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
if (!GENERAL)
return;
_X1 = _X2; // setup for FLAT_TOP.
_Y1 = _Y2;
_U1 = _U2;
_V1 = _V2;
_A1 = _A2;
h1 = h2;
_X2 = _X3;
_U2 = _U3;
_V2 = _V3;
_A2 = _A3;
h2 = h3;
_X3 = old_X3;
_Y3 = old_Y3;
_U3 = old_U3;
_V3 = old_V3;
_A3 = old_A3;
h3 = oldh3;
Buffer=_RendBuffer; // save starting point of Buffer.
FLAT_TOP:
if (_X2<_X1)
{
tempx=_X2; _X2=_X1; _X1=tempx;
tempu=_U2; _U2=_U1; _U1=tempu;
tempv=_V2; _V2=_V1; _V1=tempv;
tempa=_A2; _A2=_A1; _A1=tempa;
temph=h2; h2=h1; h1=temph;
}
height = 65536/(_Y3-_Y1);
LeftDx = (_X3-_X1)*height; // Inverse left and right slope.
RightDx = (_X3-_X2)*height;
LeftDu = (_U3-_U1)*height;
LeftDv = (_V3-_V1)*height;
RightDu = (_U3-_U2)*height;
RightDv = (_V3-_V2)*height;
LeftDa = (_A3-_A1)*height; // compute intensity deltas.
RightDa = (_A3-_A2)*height;
LeftDh = (h3-h1)*height;
RightDh = (h3-h2)*height;
LeftX = _X1<<16;
RightX = (_X2<<16)+32768;
LeftU = _U1<<16;
LeftV = _V1<<16;
RightU = _U2<<16;
RightV = _V2<<16;
LeftA = _A1<<16; // assign intensity to left and right side.
RightA = _A2<<16;
LeftH = h1<<16;
RightH = h2<<16;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
if (_Y1 < _MinClipY)
{
ydiff = (_MinClipY - _Y1);
LeftX = LeftX+LeftDx*ydiff;
RightX = RightX+RightDx*ydiff;
LeftU = LeftU+LeftDu*ydiff;
RightU = RightU+RightDu*ydiff;
LeftV = LeftV+LeftDv*ydiff;
RightV = RightV+RightDv*ydiff;
LeftA = LeftA+LeftDa*ydiff;
RightA = RightA+RightDa*ydiff;
LeftH = LeftH+LeftDh*ydiff;
RightH = RightH+RightDh*ydiff;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
_Y1 = _MinClipY;
}
if (_Y3 > _MaxClipY)
_Y3 = _MaxClipY;
Buffer+=(_Y1<<8)+(_Y1<<6);
if (_X1>=_MinClipX && _X1<=_MaxClipX &&
_X2>=_MinClipX && _X2<=_MaxClipX &&
_X3>=_MinClipX && _X3<=_MaxClipX)
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
MiddleH=LeftH;
for (x=( ClipLeftX );x<=( ClipRightX );x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa; // update the intensities and slopes.
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
else
{
for (y=_Y1;y<_Y3;y++,Buffer+=SCREENWIDTH)
{
u=LeftU;
v=LeftV;
MiddleA=LeftA;
MiddleH=LeftH;
if (ClipLeftX < _MinClipX)
{
if (ClipRightX <= _MinClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
u = LeftU + (_MinClipX - ClipLeftX)*ScanU;
v = LeftV + (_MinClipX - ClipLeftX)*ScanV;
MiddleA = LeftA + (_MinClipX - ClipLeftX)*MiddleDa; // move the intensity by
MiddleH = LeftH + (_MinClipX - ClipLeftX)*MiddleDh;
ClipLeftX = _MinClipX; // the clipped amount.
}
if (ClipRightX > _MaxClipX)
{
if (ClipLeftX > _MaxClipX)
{
LeftX += LeftDx; // update the intensities and slopes.
RightX += RightDx; // before continuing.
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
continue;
}
ClipRightX = _MaxClipX;
}
for (x=ClipLeftX;x<ClipRightX;x++)
{
Buffer[x]=HazeTBL[ (LookPalPhong[ TextureMap[ (u>>16)+( (v>>16)<<8) ] + PhongTBL[ (MiddleA>>16) ] ]<<6) + (MiddleH>>16) ];
u+=ScanU;
v+=ScanV;
MiddleA+=MiddleDa;
MiddleH+=MiddleDh;
}
LeftX += LeftDx;
RightX += RightDx;
LeftU += LeftDu;
LeftV += LeftDv;
RightU += RightDu;
RightV += RightDv;
LeftA += LeftDa;
RightA += RightDa;
LeftH += LeftDh;
RightH += RightDh;
ClipLeftX = ( LeftX>>16 );
ClipRightX = ( RightX>>16 );
width = 1+ClipRightX-ClipLeftX;
ScanU = (RightU-LeftU)/width;
ScanV = (RightV-LeftV)/width;
MiddleDa = (RightA-LeftA)/width;
MiddleDh = (RightH-LeftH)/width;
}
}
}